package cn.net.yugu.doraemon.netty.protocol.msg08;

import cn.net.yugu.doraemon.netty.msg.TypeOperator;
import cn.net.yugu.doraemon.netty.protocol.MsgCode;
import io.netty.buffer.ByteBuf;
import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

public class Msg081000014 extends Msg081 {
    private final static Logger log = LoggerFactory.getLogger(Msg081000014.class);

    public static final byte[] EMPTY_IMEI_CODE = new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    public String checkSum;
    public Boolean checkCRC;
    public String code;
    public int boxSize;
    public List<Box> boxList = new ArrayList<Box>(20);


    public static String getCRC(byte[] bytes) {
        int CRC = 0x0000ffff;
        int POLYNOMIAL = 0x0000a001;

        int i, j;
        for (i = 0; i < bytes.length; i++) {
            CRC ^= ((int) bytes[i] & 0x000000ff);
            for (j = 0; j < 8; j++) {
                if ((CRC & 0x00000001) != 0) {
                    CRC >>= 1;
                    CRC ^= POLYNOMIAL;
                } else {
                    CRC >>= 1;
                }
            }
        }
        return new String(Integer.toHexString(CRC)).toUpperCase();
    }

    @Override
    public String getCode() {
        return code;
    }

    @Override
    public int getMsgCode() {
        return MsgCode.MSG_081000014.getCode();
    }

    @Override
    public void readData(ByteBuf buffer) {
        //Content所有字节异或校验
        byte[] bytes = new byte[2];
        buffer.readBytes(bytes);
        checkSum = new String(Hex.encodeHex(bytes)).toUpperCase();
        if(checkCRC(checkSum,  buffer)){
            checkCRC = true;
        }else{
            checkCRC = false;
        }

        bytes = new byte[12];
        buffer.readBytes(bytes);
        code = new String(Hex.encodeHex(bytes)).toUpperCase();
        int boxListSize = buffer.readUnsignedByte();
        boxSize = boxListSize;
        for (int i = 0; i < boxListSize; i++) {
            Box box = new Box();
            box.read(buffer);
            boxList.add(box);
        }
    }

    public HeartParam toParam() {
        HeartParam heartParam = new HeartParam();
        heartParam.code = code;
        heartParam.boxList = new ArrayList<HeartParam.Box>(boxList.size());

        /**
         * 设备会在门状态发生变化时候才会立刻发心跳
         * 当把电池从01号拿出来，但是不关门，立刻放入02号 放入02号时候电池还是柜子中。
         * 为了解决这个问题，先处理空箱(电池取出的情况) 再处理满箱(电池放入的情况)
         */
        for (Box e : boxList) {
            if (e.batteryCode.equals(HeartParam.EMPTY_IMEI_CODE)) {
                HeartParam.Box box = new HeartParam.Box();
                //格口
                box.boxNum = e.boxNum;
                //电池
                box.batteryCode = null;
                box.temp = e.temp;
                box.serials = e.serials;
                box.singleVoltage = e.singleVoltage;
                heartParam.boxList.add(box);
            }
        }

        for (Box e : boxList) {
            if (!e.batteryCode.equals(HeartParam.EMPTY_IMEI_CODE)) {
                HeartParam.Box box = new HeartParam.Box();
                //格口
                box.boxNum = e.boxNum;

                //电池
                box.batteryCode = e.batteryCode;
                box.temp = e.temp;
                box.serials = e.serials;
                box.singleVoltage = e.singleVoltage;
                heartParam.boxList.add(box);
            }
        }

        return heartParam;
    }
    public static class Box extends TypeOperator {
        public byte boxNum;
        public String batteryCode;
        public int serials;
        public String temp;
        public String singleVoltage;

        public void read(ByteBuf buffer) {
            this.boxNum = buffer.readByte();
            //电池
            byte[] bytes = new byte[15];
            buffer.readBytes(bytes);
            for (int i = 0; i < bytes.length; i ++) {
                if (bytes[i] < 0x30) {
                    bytes[i] = (byte) (bytes[i] + 0x30);
                }
            }
            try {
                batteryCode = new String(bytes, "UTF-8");
                //智租电池特殊处理
                if(batteryCode.startsWith("B") && batteryCode.contains("YS") && batteryCode.length() == 15){
                    batteryCode = batteryCode.substring(0,batteryCode.length() -1);
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            temp = "";
            int tempSize = buffer.readByte();
            for(int i =0;i< tempSize;i++){
                if(i == tempSize -1){
                    temp +=  (buffer.readShort()  - 2731) / 10 ;
                }else{
                    temp +=  (buffer.readShort()  - 2731) / 10 +",";
                }
            }

            singleVoltage = "";
            int volSize = buffer.readByte();
            this.serials = volSize;
            for(int i =0;i< volSize;i++){
                if(i == volSize -1){
                    singleVoltage +=  buffer.readShort();
                }else{
                    singleVoltage +=  buffer.readShort() +",";
                }
            }
        }
    }
}
